﻿#include "FrameQueue.h"

FrameQueue::FrameQueue()
{
    m_sema.reset(new QSemaphore());
}

FrameQueue::~FrameQueue()
{
    std::lock_guard<std::mutex> lock(m_m);
    while(!m_q.empty()) {
        auto frame = m_q.front();
        m_q.pop_front();
        av_frame_free(&frame);
    }
}

bool FrameQueue::isEmpty()
{
    std::lock_guard<std::mutex> lock(m_m);
    return m_q.empty();
}

bool FrameQueue::push(AVFrame *frame)
{
    m_m.lock();
    m_q.push_front(frame);
    m_m.unlock();
    m_sema->release();
    return true;
}

AVFrame *FrameQueue::pop(int timeout)
{
    auto b = m_sema->tryAcquire(1, timeout);
    if(!b)
        return nullptr;

    m_m.lock();
    auto frame = m_q.back();
    m_q.pop_back();
    m_m.unlock();

    return frame;
}

int FrameQueue::size()
{
    std::lock_guard<std::mutex> lock(m_m);
    return m_q.size();
}

void FrameQueue::clear()
{
    while(!isEmpty()) {
        auto frame = pop();
        av_frame_free(&frame);
    }
}

DecodecSerial FrameQueue::serial()
{
    std::lock_guard<std::mutex> lock(m_serialMutex);
    return m_serial;
}

void FrameQueue::setSerial(const DecodecSerial& s)
{
    std::lock_guard<std::mutex> lock(m_serialMutex);
    m_serial = s;
    clear();
}
